package com.fyales.android.util;

import android.content.Context;
import android.content.SharedPreferences;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/**
 * SharePreference的包装类
 * @author fyales
 * @since 15/4/17.
 */
public class SPHelper {

    private static SPHelper mSPHelper;
    private static SharedPreferences mSP;
    private static final Object mLock = new Object();

    public static synchronized SPHelper getInstance(Context context) {
        if (mSPHelper == null) {
            mSPHelper = new SPHelper(context);
        }
        return mSPHelper;
    }

    private SPHelper(Context context) {
        mSP = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
    }

    /**
     * 保存String
     * @param key key
     * @param value value
     */
    public void putString(String key, String value) {
        synchronized (mLock) {
            mSP.edit().putString(key, value).apply();
        }
    }

    /**
     * 得到String
     * @param key key
     * @return String
     */
    public String getString(String key) {
        synchronized (mLock) {
            return mSP.getString(key, "");
        }
    }

    /**
     * 得到String
     * @param key key
     * @param defaultValue defaultValue
     */
    public String getString(String key, String defaultValue) {
        synchronized (mLock) {
            return mSP.getString(key, defaultValue);
        }
    }

    /**
     * 存入布尔值
     * @param key key
     * @param bool boolean
     */
    public void putBoolean(String key, boolean bool) {
        synchronized (mLock) {
            mSP.edit().putBoolean(key, bool).apply();
        }
    }

    /**
     * 得到布尔值
     * @param key key
     * @param defValue defaultValue
     * @return boolean
     */
    public Boolean getBoolean(String key, boolean defValue) {
        synchronized (mLock) {
            return mSP.getBoolean(key, defValue);
        }

    }

    /**
     * 存入整数值
     * @param key key
     * @param integer integer
     */
    public void putInteger(String key, int integer) {
        synchronized (mLock) {
            mSP.edit().putInt(key, integer).apply();
        }
    }

    /**
     * 得到整数值
     * @param key key
     * @param defValue defaultValue
     * @return  integer
     */
    public int getInteger(String key, int defValue) {
        synchronized (mLock) {
            return mSP.getInt(key, defValue);
        }
    }

    /**
     * 存入Long值
     * @param key key
     * @param value value
     */
    public void putLong(String key, long value) {
        synchronized (mLock) {
            mSP.edit().putLong(key, value).apply();
        }
    }

    /**
     * 得到Long值
     * @param key key
     * @param defValue defaultValue
     * @return long
     */
    public long getLong(String key, long defValue) {
        synchronized (mLock) {
            return mSP.getLong(key, defValue);
        }
    }

    /**
     * 以HashMap的形式进行保存
     * @param key key
     * @param map HashMap
     */
    public void putHashMap(String key, HashMap<String, String> map) {
        JSONObject o = new JSONObject(map);
        synchronized (mLock) {
            mSP.edit().putString(key, o.toString()).apply();
        }
    }

    /**
     * 得到整个HashMap
     * @param key key
     * @return HashMap<String,String>
     */
    public HashMap<String, String> getHashMap(String key) {
        HashMap<String, String> map = new HashMap<>();

        String mapStr = getString(key, "{}");
        JSONObject o = null;
        try {
            o = new JSONObject(mapStr);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        if (o != null) {
            Iterator<String> iterator = o.keys();
            while (iterator.hasNext()) {
                String theKey = iterator.next();
                String theValue = o.optString(theKey);
                map.put(theKey, theValue);
            }
        }
        return map;
    }


    /**
     * 保存list 必须是String类型
     * @param key key
     * @param list list
     */
    public void putArrayList(String key, ArrayList<String> list) {
        JSONArray o = new JSONArray(list);
        putString(key, o.toString());
    }

    /**
     * 得到List
     * @param key key
     * @return ArrayList<String>
     */
    public ArrayList<String> getArrayList(String key) {
        ArrayList<String> o = new ArrayList<String>();
        String listStr = getString(key, "{}");
        JSONArray listJson;

        try {
            listJson = new JSONArray(listStr);
        } catch (Exception e) {
            return o;
        }

        if (listJson != null) {
            for (int i = 0; i < listJson.length(); i++) {
                String temp = listJson.optString(i);
                o.add(temp);
            }
        }

        return o;
    }

    /**
     * 存入JSONArray
     * @param key key
     * @param value value
     */
    public void putJsonArray(String key, JSONArray value) {
        putString(key, value.toString());
    }

    /**
     * 得到JSONArray
     * @param key key
     * @return JSONArray
     */
    public JSONArray getJsonArray(String key) {
        JSONArray o = null;
        String jsonArrayStr = getString(key);
        try {
            o = new JSONArray(jsonArrayStr);
        } catch (JSONException e) {
            o = null;
        }
        return o;
    }

    /**
     * 存入对象
     * @param key key
     * @param obj 对象
     */
//    public void putObject(String key, Object obj) {
//        String s = JSON.toJSONString(obj);
//        putString(key, s);
//    }

    /**
     * 得到对象
     * @param key 键值
     * @param cls 对象的class
     * @param <T> 对象
     * @return 对象
     */
//    public <T> T getObject(String key, Class<T> cls) {
//        String s = getString(key);
//
//        if (s == null || s.trim().length() == 0) {
//            return null;
//        }
//        return JSON.parseObject(s, cls);
//    }

    /**
     * 移除键值
     * @param key 键值
     */
    public void removeKey(String key) {
        synchronized (mLock) {
            mSP.edit().remove(key).apply();
        }
    }

    /**
     * 清除所有数据
     */
    public void clear() {
        synchronized (mLock) {
            mSP.edit().clear().apply();
        }
    }

}
